﻿using AutoMapper;
using QYmall.Core.Common.Emum;
using QYmall.Core.Common.Extensions;
using QYmall.Core.Common.Helper;
using QYmall.Core.DBFactory.Database;
using QYmall.Core.IServices;
using QYmall.Core.Model.Models;
using QYmall.Core.Model.ViewModels;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace QYmall.Core.Services
{
    /// <summary>
    /// 积分兑换接口实现
    /// </summary>
    public class ShopConvertService : BaseService, IShopConvertService
    {
        private readonly IUserService _userService;
        private readonly IMapper _mapper;
        public ShopConvertService(IDbContextFactory contentFactory, IUserService userService, IMapper mapper) : base(contentFactory)
        {
            _userService = userService;
            _mapper = mapper;
        }

        /// <summary>
        /// 查询一条记录
        /// </summary>
        public async Task<ShopConvert?> QueryAsync(Expression<Func<ShopConvert, bool>> funcWhere, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            var result = await _context.Set<ShopConvert>().Include(x => x.GoodsProduct).ThenInclude(t => t!.ShopGoods)
                .FirstOrDefaultAsync(funcWhere);
            return result;
        }

        /// <summary>
        /// 查询指定数量列表
        /// </summary>
        public async Task<IEnumerable<ShopConvert>> QueryListAsync(int top, Expression<Func<ShopConvert, bool>> funcWhere,
            string orderBy, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            var result = _context.Set<ShopConvert>()
                .Include(x => x.Merchant)
                .Include(x => x.GoodsProduct).ThenInclude(t => t!.ShopGoods)
                .Where(funcWhere).OrderByBatch(orderBy);//调用Linq扩展类进行排序
            if (top > 0) result = result.Take(top);//等于0显示所有数据
            return await result.ToListAsync();
        }

        /// <summary>
        /// 查询分页列表
        /// </summary>
        public async Task<PaginationList<ShopConvert>> QueryPageAsync(int pageSize, int pageIndex, Expression<Func<ShopConvert, bool>> funcWhere,
            string orderBy, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            var result = _context.Set<ShopConvert>()
                .Include(x => x.Merchant)
                .Include(x => x.GoodsProduct).ThenInclude(t => t!.ShopGoods)
                .Where(funcWhere).OrderByBatch(orderBy);//调用Linq扩展类排序
            return await PaginationList<ShopConvert>.CreateAsync(pageIndex, pageSize, result);
        }

        /// <summary>
        /// 根据条件删除记录
        /// </summary>
        public async Task<bool> DeleteAsync(Expression<Func<ShopConvert, bool>> funcWhere, WriteRoRead writeAndRead = WriteRoRead.Write)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            var list = await _context.Set<ShopConvert>().Where(funcWhere).ToListAsync();
            if (list == null)
            {
                return false;
            }
            foreach (var modelt in list)
            {
                //删除积分兑换记录
                var historyList = await _context.Set<ShopConvertHistory>().Where(x => x.ConvertId == modelt.Id).ToListAsync();
                if (historyList != null)
                {
                    _context.Set<ShopConvertHistory>().RemoveRange(historyList);
                }
                //加入追踪列表
                _context.Set<ShopConvert>().Attach(modelt);
            }
            _context.Set<ShopConvert>().RemoveRange(list);

            return await this.SaveAsync();
        }

        /// <summary>
        /// 获取换购商品统计和列表
        /// </summary>
        public async Task<ShopCartTotalDto> GetBuyListAsync(long id, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库
            //获取当前用户信息
            var userId = await _userService.GetUserIdAsync();
            if (userId == 0)
            {
                throw new ResponseException("会员尚未登录或已超时", ErrorCode.TokenExpired, StatusCodes.Status401Unauthorized);
            }
            //获取会员组信息
            var memberModel = await _context.Set<Members>().Where(x => x.UserId == userId).Include(x => x.Group).FirstOrDefaultAsync();
            if (memberModel == null)
            {
                throw new ResponseException("会员账户不存在或已删除");
            }
            //获取换购信息
            var model = await _context.Set<ShopConvert>()
                .Include(x => x.GoodsProduct).ThenInclude(t => t!.ShopGoods)
                .FirstOrDefaultAsync(x => x.Id == id
                    && x.IsDelete == 0
                    && x.Status == 0
                    && x.GoodsProduct!.ShopGoods!.Status == 0
                    && x.GoodsProduct.StockQuantity > 0);
            if (model == null)
            {
                throw new ResponseException("换购活动不存在或已过期");
            }
            //获取商家信息
            var merchantModel = await _context.Set<Merchants>().Include(x => x.Store)
                .FirstOrDefaultAsync(x => x.Id == model.MerchantId);
            if (merchantModel == null)
            {
                throw new ResponseException("店铺信息不存在或已禁用");
            }

            //创建待赋值的实体
            int quantityNum = 1;
            ShopCartDto cartDto = new()
            {
                UserId = memberModel.UserId,
                MerchantId = model.MerchantId,
                Status = model.GoodsProduct?.ShopGoods?.Status == 0 ? (byte)0 : (byte)1,
                AddTime = DateTime.Now,
                GoodsId = model.GoodsProduct?.GoodsId ?? 0,
                Title = model.GoodsProduct?.ShopGoods?.Title,
                SkuText = model.GoodsProduct?.SkuText,
                ImgUrl = model.GoodsProduct?.ImgUrl ?? model.GoodsProduct?.ShopGoods?.ImgUrl,
                MarketPrice = model.GoodsProduct?.MarketPrice ?? 0,
                SellPrice = model.GoodsProduct?.SellPrice ?? 0,
                GroupPrice = model.GoodsProduct?.SellPrice ?? 0,
                Weight = model.GoodsProduct?.Weight ?? 0,
                StockQuantity = model.GoodsProduct?.StockQuantity ?? 0,
                ProductId = model.GoodsProduct?.Id ?? 0,
                Quantity = quantityNum
            };

            ShopCartTotalListDto resultItem = new()
            {
                MerchantId = merchantModel.Id,
                MerchantTitle = merchantModel.Title,
                MerchantAvatar = merchantModel.Avatar,
                StoreTitle = merchantModel.Store?.Title
            };
            resultItem.Goods.Add(cartDto);
            resultItem.TotalQuantity = resultItem.Goods.Select(x => x.Quantity).Sum();
            resultItem.TotalWeight = resultItem.Goods.Select(x => x.Weight).Sum();
            resultItem.TotalPoint = model.Point;
            //非免运费商品标记
            if (model.GoodsProduct?.ShopGoods?.IsDeliveryFee == 0)
            {
                resultItem.FreeFreight = 0;
            }
            resultItem.PayableAmount = resultItem.Goods.Select(x => x.SellPrice).Sum();
            resultItem.RealAmount = 0;
            resultItem.OrderAmount = resultItem.RealAmount;
            //获取商户配送列表(前10条)
            var deliveryList = await _context.Set<ShopDelivery>()
                .Include(x => x.DeliveryAreas)
                .Where(x => x.IsDelete == 0 && x.Status == 0 && x.MerchantId == model.MerchantId)
                .OrderByBatch("SortId,-Id")
                .Take(10)
                .ToListAsync();
            //转换成DTO
            resultItem.ShopDeliverys = _mapper.Map<List<ShopDeliveryCartDto>>(deliveryList);

            ShopCartTotalDto result = new();
            result.List.Add(resultItem);
            result.TotalQuantity = result.List.Select(x => x.TotalQuantity).Sum();
            result.TotalPoint = result.List.Select(x => x.TotalPoint).Sum();
            result.TotalRealAmount = result.List.Select(x => x.RealAmount).Sum();
            result.TotalOrderAmount = result.List.Select(x => x.OrderAmount).Sum();

            return result;
        }
    }
}
